<?php
/**
 * ApiSpider.php class file.
 * @author shengxia <523247758@qq.com>
 * @date 2021/2/20- 下午8:27
 */

namespace common\drivers\spiderProductGY;


use api\exceptions\CopyException;
use common\constants\PlatformConstGY;
use common\drivers\interfaces\SpiderProductInterface;
use common\exception\DriverException;
use common\helpers\AmountHelper;
use common\helpers\StringHelper;
use common\helpers\UrlsHelper;
use console\components\helpers\ConsoleHelper;

use yii\db\Exception;

class ApiSpider extends BaseSpider implements SpiderProductInterface
{

    /**
     * 获取商品数据接口
     * @var string
     */
    protected $requestUrl = 'http://analysis.mebei.vip/';

    protected $app_key = '3874993';

    protected $app_secret = 'F7112C73D05A2A3EDFF745C3AD213FCF';

    protected $callbackUrl = 'http://192.168.1.10:8000/collectback/api';
    /**
     * 失败重试3次
     * @var int
     */
    protected $tryTimes = 3;
    /**
     * 重试等待秒数
     * @var int
     */
    protected $waitTimes = 1;
    protected $platform = null;

    /**
     * 获取api数据
     * @param string $url
     * @return string
     * @throws DriverException
     */
    public function getContents(string $url): string
    {

        $this->platform = UrlsHelper::getUrlSourceGY($url);


        $num_iid = UrlsHelper::getUrlPrimaryKeyGY($this->platform, $url);


        $contentTimes = 0;
        while ($contentTimes < $this->tryTimes) {
            $contents = $this->itemDataGet($num_iid, $this->platform);
            if (!$contents) {
                $contentTimes++;
                ConsoleHelper::runInfo("抓取api货源信息失败，即将重试第{$contentTimes}次");
                continue;
            }
            //$this->resources = $contents;
//            $results = $this->itemDataCallBack($content['list']['request_id']);
//            $this->resources = $results;
            break;
        }
        return $contents;
    }

    public function getContent(string $num_iids, int $platform)
    {

        $contentTimes = 0;
        $contents = '';
        while ($contentTimes < $this->tryTimes) {
            $contents = $this->itemDataGet($num_iids, $platform);
            if (!$contents) {
                $contentTimes++;
                ConsoleHelper::runInfo("抓取api货源信息失败，即将重试第{$contentTimes}次");
                continue;
            }
            $contents = json_decode($contents, true);
            break;
//            $results = $this->itemDataCallBack($contents['list']['request_id']);
//            $results = json_decode($results,true);
//            echo "<pre>";
//            print_r($results);
//            exit();
//            $this->resources = $results;
//            break;
        }
        return $contents;
    }

    /**
     * 公共请请求参数
     */
    private function _getPubRequest()
    {
        return [
            'app_key' => $this->app_key,
            'timestamp' => date('Y-m-d H:i:s')
        ];
    }

    /**
     * 获取签名sign
     */
    private function _getSign(array $request)
    {
        ksort($request);
        $code = $this->app_secret;
        foreach ($request as $k => $item) {
            $code .= $k . $item;
        }
        $code .= $this->app_secret;
        return strtoupper(md5($code));
    }

    public function itemDataGet(string $itemId, int $platform = 0)
    {
        $method = 'goods/index';
        $request = array_merge([
            'num_iid' => $itemId,
            'platform' => $platform,
            'callback' => $this->callbackUrl
        ], $this->_getPubRequest());
        $sign = $this->_getSign($request);
        $request['sign'] = $sign;
        //$response = $this->httpPost($this->requestUrl . $method, $request);
        $resources = $this->spiderContent($this->requestUrl . $method, $request);
        if (!$resources) {
            throw new DriverException('获取数据源失败');
        }
        $contents = $resources->getBody()->getContents();
        if (!$contents) {
            throw new DriverException('获取数据源失败');
        }
        return $contents;

    }

    public function itemDataCallBack(string $request_id)
    {
        $tryTimes = 0;
        while ($tryTimes < $this->tryTimes) {
            try {
                $method = 'callback/index';
                $request = array_merge([
                    'request_id' => $request_id
                ], $this->_getPubRequest());
                $sign = $this->_getSign($request);
                $request['sign'] = $sign;
                $response = $this->httpPost($this->requestUrl . $method, $request);
                return $response;
            } catch (Exception $e) {
                $tryTimes++;
                sleep($this->waitTimes);
                continue;
            }
        }


    }

    /**
     * psot方式发起请求
     */
    private function httpPost(string $sUrl, array $aData, array $aHeader = [])
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_URL, $sUrl);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($aData));
        $sResult = curl_exec($ch);
        if ($sError = curl_error($ch)) {
            die($sError);
        }
        curl_close($ch);
        return $sResult;
    }

    /**
     * @inheritDoc
     * @return array
     * @throws DriverException
     */
    public function formatContent(array $arr = [])
    {

        $this->resources = $arr;
        if (!isset($this->resources) || empty($this->resources)) {
            throw new DriverException('数据源不存在或已下架');
        }
        $this->productInfo['cid'] = $this->resources['cate_id'];

        $this->productInfo['platform'] = $this->resources['platform'];

        $this->productInfo['mall_name'] = isset($this->resources['mall_name']) && !empty($this->resources['mall_name']) ?
            trim($this->resources['mall_name']) : '';

        $this->productInfo['mall_id'] = $this->resources['mall_id'] ?? 0;

        $this->productInfo['title'] = $this->resources['title'] ?? '';
        $this->productInfo['prices'] = isset($this->resources['price']) ? intval($this->resources['price']) : 0;

        $this->productInfo['num_iid'] = $this->resources['goods_id'] ?? 0;

        $this->productInfo['main_pic'] = $this->resources['thumb'] ?? '';

        if (isset($this->resources['video']) && !empty($this->resources['video'])) {
            $this->productInfo['video'] = $this->resources['video'];
        }
        $this->productInfo['pics'] = StringHelper::jsonDecode($this->resources['main_figures']); //主图
        $this->productInfo['detail_gallery'] = StringHelper::jsonDecode($this->resources['detail_figures']); //详情图
        //商品详情，纯文本
        $this->productInfo['goods_desc'] = $this->resources['desc'] ?? '';
        //邮费字段
        $this->productInfo['postage'] = 0;
        if (isset($this->resources['postage'])) {
            $this->productInfo['postage'] = $this->resources['postage'];
        }
        //属性
        if (isset($this->resources['properties']) && !empty($this->resources['properties'])) {
            $properties = StringHelper::jsonDecode($this->resources['properties']);

            if (is_array($properties) && count($properties)) {
                $this->productInfo['attr'] = $properties;
            }
        }
        /**
         * sku 设置
         */
        $this->setSku();

        $this->setPcDesc();

        /**
         * 其他扩展字段
         */
        $this->setExtend();
        return $this->productInfo;

    }

    /**
     * @inheritDoc
     * @return array
     * @throws DriverException
     */
    public function formatContents(): array
    {

        $this->resources = StringHelper::jsonDecode($this->resources)['list']['goodsItem'][0];
        if (!isset($this->resources) || empty($this->resources)) {
            throw new DriverException('数据源不存在或已下架');
        }
        $this->productInfo['cid'] = $this->resources['cate_id'];

        $this->productInfo['platform'] = $this->platform;

        $this->productInfo['mall_name'] = isset($this->resources['mall_name']) && !empty($this->resources['mall_name']) ?
            trim($this->resources['mall_name']) : '';

        $this->productInfo['mall_id'] = $this->resources['mall_id'] ?? 0;

        $this->productInfo['title'] = $this->resources['title'] ?? '';
        $this->productInfo['prices'] = isset($this->resources['price']) ? intval($this->resources['price']) : 0;

        $this->productInfo['num_iid'] = $this->resources['goods_id'] ?? 0;

        $this->productInfo['main_pic'] = $this->resources['thumb'] ?? '';

        if (isset($this->resources['video']) && !empty($this->resources['video'])) {
            $this->productInfo['video'] = $this->resources['video'];
        }
        $this->productInfo['pics'] = StringHelper::jsonDecode($this->resources['main_figures']); //主图

        $this->productInfo['detail_gallery'] = StringHelper::jsonDecode($this->resources['detail_figures']); //详情图
        //商品详情，纯文本
        $this->productInfo['goods_desc'] = $this->resources['desc'] ?? '';
        //邮费字段
        if (isset($this->resources['postage']) && !empty($this->resources['postage'])) {
            $this->productInfo['postage'] = $this->resources['postage'];
        }
        //属性
        if (isset($this->resources['properties']) && !empty($this->resources['properties'])) {
            $properties = StringHelper::jsonDecode($this->resources['properties']);

            if (is_array($properties) && count($properties)) {
                $this->productInfo['attr'] = $properties;
            }
        }
        /**
         * sku 设置
         */
        $this->setSku();

        $this->setPcDesc();

        /**
         * 其他扩展字段
         */
        $this->setExtend();
        return $this->productInfo;

    }


    private function setExtend()
    {
        $this->productInfo['extend_data'] = [
            'fav_count' => $this->resources['fav_count'] ?? 0, //收藏量
            'total_sold' => $this->resources['total_sold'] ?? 0, //评论数
            'sales' => $this->resources['sold_total'] ?? 0, //销量
            'pre_sale_stamp' => $this->resources['pre_sale_stamp'] ?? 0, //预售时间，单位秒
            'post_fee' => $this->resources['post_fee'] ?? 0, //物流费用
            'express_fee' => $this->resources['express_fee'] ?? 0, //快递费用
            'location' => $this->resources['location'] ?? '', //发货地
            'mall_goods_num' => $this->resources['mall_goods_num'] ?? 0, //店铺所有商品数量
            'mall_sold_total' => $this->resources['mall_sold_total'] ?? 0, //店铺所有商品总销量
            'delivery_time' => $this->resources['delivery_time'] ?? '', //承诺多长时间发货，单位小时
        ];
    }

    /**
     * 设置sku信息
     */
    protected function setSku()
    {
        $propsList = $propsType = [];

        if (isset($this->resources['sku_products']) && !empty($this->resources['sku_products'])) {
            $propsList = StringHelper::jsonDecode($this->resources['sku_products']);
        }

        if (isset($this->resources['sku_big_types']) && !empty($this->resources['sku_big_types'])) {
            $propsType = StringHelper::jsonDecode($this->resources['sku_big_types']);
        }
//
//        print_r($propsList);
//        print_r($propsType); exit;

        $transSkuIds = [];
        /**
         * skuImg
         */
        if (count($propsType)) {
            foreach ($propsType as $t => $propImg) {
                if (is_array($propImg['values'])) {
                    foreach ($propImg['values'] as $_v => $val) {
                        //只取第一条作为颜色图sku
                        if ($t == 0) {
                            $tmp = [];
                            $tmp['name'] = $propImg['name'];
                            $tmp['value'] = $val;
                            $tmp['skuImg'] = '';
                            $tmp['key'] = ($t + 1) . ':' . $_v;
                            $this->productInfo['sku_img'][$_v] = $tmp;
                        }
                        $transSkuIds[$_v] = ['name' => $propImg['name'] . ':' . $val, 'ids' => ($t + 1) . ':' . $_v];
                    }
                }
            }
        }
        /**
         * sku
         *  "properties":"["20509:12430610","1627207:28321"]",
         *  "properties_name":"["尺码:M（56-58cm）","颜色分类:白色"]",
         */
        if (count($propsList)) {
            foreach ($propsList as $k => $sku) {
                if ((isset($sku['price']) && $sku['price'] > 0) && (isset($sku['is_sale']) && $sku['is_sale'] == 1) && (isset($sku['quantity']) && $sku['quantity'] > 0)) {
                    $tmp = [];
                    $tmp['skuId'] = $sku['id'] ?? 0;
                    $tmp['stock'] = $sku['quantity'] ?? 0;
                    $tmp['price'] = isset($sku['price']) ? AmountHelper::fenToYuan((int)$sku['price']) : 0; //原价
                    $tmp['sale_price'] = isset($sku['sale_price']) ? AmountHelper::fenToYuan((int)$sku['sale_price']) : $tmp['price']; //销售价
                    $tmp['properties'] = [];
                    $tmp['properties_name'] = [];
                    $tmp['cover'] = $sku['url'] ?? ''; //防止sku中存在没有图片的情况导致数据格式不一致
                    if (is_array($sku['skus'])) {
                        foreach ($sku['skus'] as $props) {
                            if (isset($transSkuIds[$props])) {
                                array_push($tmp['properties'], $transSkuIds[$props]['ids']);
                                array_push($tmp['properties_name'], $transSkuIds[$props]['name']);
                            }
                        }

                        foreach ($this->productInfo['sku_img'] as $p => $prop) {
                            if (in_array($p, $sku['skus'])) {
                                $this->productInfo['sku_img'][$p]['skuImg'] = $sku['url'];
                            }
                        }
                    }
                    $tmp['properties_name'] = StringHelper::jsonEncode($tmp['properties_name']);
                    $tmp['properties'] = StringHelper::jsonEncode($tmp['properties']);
                    array_push($this->productInfo['skus'], $tmp);
                }
            }
        }
        $this->productInfo['sku_img'] = array_values($this->productInfo['sku_img']);
    }

    /**
     * @inheritDoc
     */
    public function setErrorInfo(string $msg = '')
    {

    }

    /**
     * 设置下电脑端的描叙详情
     */
    private function setPcDesc()
    {
        if ($this->productInfo['detail_gallery']) {
            if (count($this->productInfo['detail_gallery'])) {
                $pc_desc = '<p>';
                foreach ($this->productInfo['detail_gallery'] as $k => $img) {
                    $pc_desc .= '<img src="' . $img . '" align="absmiddle" />';
                }
                $pc_desc .= '</p>';

                $this->productInfo['pc_desc'] = $pc_desc;
            }
        }

    }

    /**
     * @inheritDoc
     */
    public function getErrorInfo()
    {
        return $this->errorInfo;
    }

    /**
     * @inheritDoc
     */
    public function saveDb()
    {

    }
}